/*	talmud - The TALMUD roguelike
 * Copyright (C) 2012, talmud contributors
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of Version 2 of the GNU General Public License as published
 *  by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE. See Version 2 of the GNU General Public
 *  License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include "draw.h"

static uint8_t cx;
static uint8_t cy;
static uint8_t color;
static uint8_t framebuffer[80 * 24];
static uint8_t attrbuffer[80 * 24];
static uint8_t lastframebuffer[80 * 24];
static uint8_t lastattrbuffer[80 * 24];

void Cls(void)
{
	//memset(lastframebuffer, ' ', 80 * 24);
	//memset(lastattrbuffer, A_WHITE, 80 * 24);
	memset(framebuffer, ' ', 80 * 24);
	memset(attrbuffer, A_WHITE, 80 * 24);
}

void Cll(uint8_t x, uint8_t y)
{
	memset(&framebuffer[y * 80 + x], ' ', 80 - x);
	memset(&attrbuffer[y * 80 + x], A_WHITE, 80 - x);
}

void InitDraw(void)
{
	memcpy(lastframebuffer, framebuffer, 80 * 24);
	memcpy(lastattrbuffer, attrbuffer, 80 * 24);
	color = A_WHITE;
	memset(framebuffer, ' ', 80 * 24);
	memset(attrbuffer, color, 80 * 24);
}

void SetColor(uint8_t c)
{
	color = c;
}

void DrawChar(uint8_t x, uint8_t y, uint8_t c)
{
	framebuffer[y * 80 + x] = c;
	attrbuffer[y * 80 + x] = color;
	cx = x;
	cy = y;
}

uint8_t DrawStr(uint8_t x, uint8_t y, const char *format, ...)
{
	char buffer[80];
	va_list ap;
	uint8_t idx;
	uint8_t ret;

	va_start(ap, format);
	vsnprintf(buffer, 80, format, ap);
	va_end(ap);
	cx = x;
	cy = y;
	ret = 0;
	for (idx = 0; idx < strlen(buffer) && cx < 80; idx++)
	{
		DrawChar(cx, cy, buffer[idx]);
		cx++;
		ret++;
	}

	return ret;
}

uint8_t DrawCenteredStr(uint8_t x, uint8_t y, const char *format, ...)
{
	char buffer[80];
	va_list ap;
	uint8_t idx;
	uint8_t len;

	va_start(ap, format);
	vsnprintf(buffer, 80, format, ap);
	va_end(ap);
	len = strlen(buffer);
	if (x > (len >> 1))
	{
		cx = x - (len >> 1);
	}
	else
	{
		cx = 0;
	}
	cy = y;
	for (idx = 0; idx < strlen(buffer) && cx < 80; idx++)
	{
		DrawChar(cx, cy, buffer[idx]);
		cx++;
	}

	return len;
}

void PutCursor(uint8_t x, uint8_t y)
{
	cx = x;
	cy = y;
}

void FlushDraw(void)
{
	uint8_t x;
	uint8_t y;
	uint8_t attr = A_WHITE;
	uint8_t lastattr = A_WHITE;
	char colorcode[8];

	printf("\033[H\033[2J\033[0m");
	for (y = 0; y < 24; y++)
	{
		if (y)
		{
			printf("\033[%iH", y + 1);
		}
		for (x = 0; x < 80; x++)
		{
			if (attrbuffer[y * 80 + x] != attr)
			{
				lastattr = attr;
				attr = attrbuffer[y * 80 + x];
				if (attr & A_INTENSE)
				{
					strcpy(colorcode, "1;");
				}
				else if (lastattr & A_INTENSE || lastattr & A_BGMASK)
				{
					strcpy(colorcode, "0;");
				}
				else
				{
					strcpy(colorcode, "");
				}
				if (attr & A_BGMASK)
				{
					sprintf(colorcode, "%s%i;", colorcode, 40 + ((attr & A_BGMASK) >> 4));
				}
				sprintf(colorcode, "%s%i", colorcode, 30 + (attr & A_COLORMASK));
				printf("\033[%sm%c", colorcode, framebuffer[y * 80 + x]);
			}
			else
			{
				putc(framebuffer[y * 80 + x], stdout);
			}
		}
	}
	printf("\033[%i;%iH", cy + 1, cx + 1);
	fflush(stdout);
}
